package com.xlh.openai.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.service.WxPayService;
import com.xlh.openai.dao.ProductDao;
import com.xlh.openai.entity.OrderEntity;
import com.xlh.openai.entity.ProductEntity;
import com.xlh.openai.entity.WechatUserEntity;
import com.xlh.openai.entity.enums.IsNotStatus;
import com.xlh.openai.exception.ServiceException;
import com.xlh.openai.service.OrderService;
import com.xlh.openai.service.ProductService;
import com.xlh.openai.service.WechatUserService;
import com.xlh.openai.utils.RequestUtil;
import com.xlh.openai.vo.MallOrderCreateVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.Optional;


@Service("productService")
public class ProductServiceImpl extends ServiceImpl<ProductDao, ProductEntity> implements ProductService {

    @Autowired
    private WechatUserService wechatUserService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private OrderService orderService;

    @Override
    public MallOrderCreateVO pay(Integer productId, HttpServletRequest request, HttpSession session) {

        String openId = wechatUserService.getOpenIdBySession(session);
        WechatUserEntity wechatUserEntity = wechatUserService.getByOpenId(openId);
        String ip = RequestUtil.getIpAddress(request);
        Optional<ProductEntity> productOpt = Optional.ofNullable(getById(productId));
        productOpt.orElseThrow(()-> new ServiceException("未查询到指定商品！"));
        ProductEntity productEntity = productOpt.get();
        if(productEntity.getStock() <= 0){
            throw new ServiceException("商品紧缺，正在紧急上货中ing！");
        }
        OrderEntity orderEntity = orderService.createOrder(productOpt.get(), wechatUserEntity.getId());
        // 根据商品创建订单
        MallOrderCreateVO wxOrder = createWxOrder(openId, ip, orderEntity);

        return wxOrder;
    }

    @Override
    public void decrease(Integer id, Integer stock) {

        UpdateWrapper<ProductEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(ProductEntity::getStock, (stock-1))
                .eq(ProductEntity::getId, id);
        update(updateWrapper);
    }

    @Override
    public void increase(Integer id, Integer stock) {

        UpdateWrapper<ProductEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(ProductEntity::getStock, (stock+1))
                .eq(ProductEntity::getId, id);
        update(updateWrapper);
    }

    @Override
    public ProductEntity getExchangeProduct() {
        QueryWrapper<ProductEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProductEntity::getIsExchange, IsNotStatus.IS.getCode());
        return getOne(queryWrapper);
    }

    private MallOrderCreateVO createWxOrder(String openid, String ip, OrderEntity order) {

        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setBody("兑换商品");
        orderRequest.setOutTradeNo(order.getOutTradeNo());
        BigDecimal productFee = order.getTotalPrice();
        orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(productFee.stripTrailingZeros().toPlainString()));
        orderRequest.setOpenid(openid);
        orderRequest.setSpbillCreateIp(ip);
        orderRequest.setTimeExpire(DateUtil.format(order.getTimeExpire(),"yyyyMMddHHmmss"));
        orderRequest.setTradeType("JSAPI");

        WxPayMpOrderResult wxPayMpOrderResult;
        try {
            wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("支付失败，请稍后重试！");
        }
        return new MallOrderCreateVO().setId(order.getId())
                .setPay(true).setAppId(wxPayMpOrderResult.getAppId())
                .setTimeStamp(wxPayMpOrderResult.getTimeStamp())
                .setNonceStr(wxPayMpOrderResult.getNonceStr())
                .setPackageValue(wxPayMpOrderResult.getPackageValue())
                .setPaySign(wxPayMpOrderResult.getPaySign())
                .setSignType(wxPayMpOrderResult.getSignType());
    }

}